<?php

namespace app\admin\controller\ai;
include_once APP_PATH . 'api/common.php';
use app\common\controller\Backend;
use think\Exception;
use think\Config;
use think\Log;
use think\Cache;

/**
 * AI应用控制器
 * 提供AI相关的通用功能，包括图片生成和文本生成
 */
class Ai extends Backend
{
    protected $noNeedLogin = ['*'];
    protected $noNeedRight = ['*'];

    /**
     * AI配置
     */
    private $aiConfig;
    
    /**
     * 服务商切换缓存键
     */
    private $providerSwitchKey = 'ai_provider_switch';
    
    /**
     * 服务商优先级列表
     */
    private $providerPriority = ['qianwen', 'stable_diffusion', 'stable_diffusion2'];
    
    /**
     * 切换持续时间（30分钟）
     */
    private $switchDuration = 1800; // 30分钟 = 1800秒

    public function _initialize()
    {
        parent::_initialize();

        // 加载AI配置 - 使用多种方式尝试加载
        $this->aiConfig = null;

        // 方法1: 使用config助手函数
        if (function_exists('config')) {
            $this->aiConfig = config('ai');
       }

        // 方法2: 使用Config类
        if (empty($this->aiConfig) && class_exists('\\think\\Config')) {
            $this->aiConfig = \think\Config::get('ai');
        }

        // 方法3: 直接包含配置文件
        if (empty($this->aiConfig)) {
            $configFile = APP_PATH . 'extra/ai.php';
            if (file_exists($configFile)) {
                $this->aiConfig = include $configFile;
            }
        }

        // 记录配置加载结果（静默处理，避免在初始化时输出）
        try {
            $this->writeLog("AI配置加载: " . (is_array($this->aiConfig) ? '成功' : '失败'));

            if (!is_array($this->aiConfig) || empty($this->aiConfig)) {
                $this->writeLog("AI配置加载失败，配置类型: " . gettype($this->aiConfig), 'error');
            }
        } catch (\Exception $e) {
            // 静默处理初始化错误
        }
    }

    /**
     * 记录日志的简单方法
     */
    private function writeLog($message, $type = 'info')
    {
        try {
            $logFile = $_SERVER["DOCUMENT_ROOT"] . "/../runtime/ai.log";
            $time = date('Y-m-d H:i:s');
            $content = "[{$time}] [{$type}] {$message}\n";

            // 确保目录存在
            $logDir = dirname($logFile);
            if (!is_dir($logDir)) {
                @mkdir($logDir, 0755, true);
            }

            @file_put_contents($logFile, $content, FILE_APPEND | LOCK_EX);
        } catch (\Exception $e) {
            // 日志写入失败时不抛出异常，避免影响主要功能
        }
    }

    /**
     * 获取当前可用的服务商
     */
    private function getCurrentProvider($requestedProvider = null)
    {
        // 检查是否有切换记录
        $switchInfo = Cache::get($this->providerSwitchKey);
        
        if ($switchInfo && is_array($switchInfo)) {
            $currentTime = time();
            $switchTime = $switchInfo['switch_time'] ?? 0;
            $switchedProvider = $switchInfo['provider'] ?? null;
            
            // 如果切换时间未超过30分钟，继续使用切换后的服务商
            if (($currentTime - $switchTime) < $this->switchDuration && $switchedProvider) {
                $this->writeLog("使用切换后的服务商: {$switchedProvider}，剩余时间: " . ($this->switchDuration - ($currentTime - $switchTime)) . "秒");
                return $switchedProvider;
            } else if (($currentTime - $switchTime) >= $this->switchDuration) {
                // 30分钟后，清除切换记录，恢复默认服务商
                Cache::rm($this->providerSwitchKey);
                $this->writeLog("切换时间已过，恢复默认服务商");
            }
        }
        
        // 返回请求的服务商或默认服务商
        return $requestedProvider ?: ($this->aiConfig['default_provider'] ?? 'qianwen');
    }

    /**
     * 切换到下一个可用的服务商
     */
    private function switchToNextProvider($currentProvider)
    {
        $currentIndex = array_search($currentProvider, $this->providerPriority);
        
        if ($currentIndex === false) {
            $currentIndex = 0;
        }
        
        // 获取下一个服务商
        $nextIndex = $currentIndex + 1;
        if ($nextIndex >= count($this->providerPriority)) {
            // 如果已经是最后一个，返回null表示无更多备用
            $this->writeLog("已尝试所有服务商，无更多备用选项");
            return null;
        }
        
        $nextProvider = $this->providerPriority[$nextIndex];
        
        // 记录切换信息到缓存
        $switchInfo = [
            'provider' => $nextProvider,
            'switch_time' => time(),
            'from_provider' => $currentProvider,
            'reason' => 'connection_failed'
        ];
        
        Cache::set($this->providerSwitchKey, $switchInfo, $this->switchDuration + 60); // 多缓存1分钟防止边界问题
        
        $this->writeLog("服务商切换: {$currentProvider} -> {$nextProvider}");
        
        return $nextProvider;
    }

    /**
     * 测试服务商连接
     */
    private function testProviderConnection($provider)
    {
        try {
            $this->writeLog("测试服务商连接: {$provider}");
            
            // 简单的连接测试
            $config = $this->aiConfig[$provider] ?? null;
            if (!$config) {
                $this->writeLog("服务商配置不存在: {$provider}");
                return false;
            }
            
            $apiUrl = $config['api_url'] ?? '';
            if (empty($apiUrl)) {
                $this->writeLog("服务商API URL为空: {$provider}");
                return false;
            }
            
            // 简单的HTTP连接测试
            $ch = curl_init();
            curl_setopt_array($ch, [
                CURLOPT_URL => $apiUrl,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_TIMEOUT => 5, // 5秒超时
                CURLOPT_CONNECTTIMEOUT => 3, // 3秒连接超时
                CURLOPT_NOBODY => true, // 只获取头部
                CURLOPT_SSL_VERIFYPEER => false,
                CURLOPT_SSL_VERIFYHOST => false
            ]);
            
            $result = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            $error = curl_error($ch);
            curl_close($ch);
            
            if ($result === false || !empty($error)) {
                $this->writeLog("服务商连接失败: {$provider}, 错误: {$error}");
                return false;
            }
            
            // HTTP状态码检查（200-299为成功，400+为客户端/服务器错误但连接正常）
            if ($httpCode >= 200 && $httpCode < 500) {
                $this->writeLog("服务商连接正常: {$provider}, HTTP状态码: {$httpCode}");
                return true;
            }
            
            $this->writeLog("服务商连接异常: {$provider}, HTTP状态码: {$httpCode}");
            return false;
            
        } catch (\Exception $e) {
            $this->writeLog("服务商连接测试异常: {$provider}, 错误: " . $e->getMessage());
            return false;
        }
    }

    /**
     * AI自动生成图片（改进版）
     */
    public function generateImage()
    {
        if (!$this->request->isPost()) {
            return json(['code' => 0, 'msg' => '请求方式错误']);
        }

        // 检查AI配置是否加载成功
        if (!is_array($this->aiConfig) || empty($this->aiConfig)) {
            $this->writeLog("AI配置检查失败", 'error');
            return json(['code' => 0, 'msg' => 'AI配置未找到或格式错误']);
        }

        // 获取请求的服务商
        $requestedProvider = $this->request->post('provider', '');
        $provider = $this->getCurrentProvider($requestedProvider);
        
        // 获取其他参数
        $prompt = $this->request->post('prompt', '');
        $width = $this->request->post('width', '');
        $height = $this->request->post('height', '');
        $type = $this->request->post('type', '');
        $style = $this->request->post('style', 'school_poster');
        $size = $this->request->post('size', '');

        // 记录接收到的参数
        $this->writeLog("接收到的参数: prompt={$prompt}, width={$width}, height={$height}, type={$type}, style={$style}, size={$size}, provider={$provider}");

        // 构建尺寸字符串
        if ($width && $height) {
            $size = $width . '*' . $height;
        } elseif ($size) {
            if (strpos($size, '*') !== false) {
                list($width, $height) = explode('*', $size, 2);
            } elseif (strpos($size, 'x') !== false) {
                list($width, $height) = explode('x', $size, 2);
            }
        } else {
            $size = '1024*1024';
            $width = '1024';
            $height = '1024';
        }

        $width = (int)$width;
        $height = (int)$height;

        if (empty($prompt)) {
            return json(['code' => 0, 'msg' => '提示词不能为空']);
        }

        // 尝试生成图片，支持自动切换服务商
        $maxAttempts = count($this->providerPriority);
        $currentProvider = $provider;
        $triedProviders = []; // 记录所有尝试过的服务商
        $lastTriedProvider = $currentProvider; // 记录最后尝试的服务商

        for ($attempt = 1; $attempt <= $maxAttempts; $attempt++) {
            try {
                $this->writeLog("第 {$attempt} 次尝试，使用服务商: {$currentProvider}");

                // 记录尝试过的服务商
                if (!in_array($currentProvider, $triedProviders)) {
                    $triedProviders[] = $currentProvider;
                }
                $lastTriedProvider = $currentProvider;

                // 检查频率限制
//                if (!$this->checkRateLimit()) {
//                    return json(['code' => 0, 'msg' => '请求过于频繁，请稍后再试']);
//                }

                // 应用风格后缀
                $styledPrompt = $this->applyStyle($prompt, $style);
                $this->writeLog("AI请求: {$prompt}");

                // 调用AI图片生成服务
                $this->writeLog("开始调用API，服务商: {$currentProvider}");
                list($newWidth, $newHeight) = $this->fangda($width, $height);
                $imageUrl = $this->callAiApi($styledPrompt, $newWidth, $newHeight, $currentProvider, $type);
                $this->writeLog("API调用成功，服务商: {$currentProvider}");

                if ($imageUrl) {
                    // 下载图片到本地
                    $localPath = $this->downloadAndSaveImage($imageUrl);
                    $imageUrl = getImg($imageUrl, $width, $height);
                    if ($localPath) {
                        $this->writeLog("图片生成成功，服务商: {$currentProvider}");
                        return json([
                            'code' => 1,
                            'msg' => 'AI图片生成成功',
                            'data' => [
                                'image_url' => $imageUrl,
                                'original_url' => $imageUrl,
                                'prompt' => $styledPrompt,
                                'size' => "{$newWidth}*{$newHeight}",
                                'style' => $style,
                                'provider' => $currentProvider,
                                'attempt' => $attempt
                            ]
                        ]);
                    } else {
                        throw new \Exception('图片保存失败');
                    }
                } else {
                    throw new \Exception('API返回空结果');
                }
                
            } catch (\Exception $e) {
                $this->writeLog("服务商 {$currentProvider} 调用失败: " . $e->getMessage(), 'error');
                
                // 如果不是最后一次尝试，切换到下一个服务商
                if ($attempt < $maxAttempts) {
                    $nextProvider = $this->switchToNextProvider($currentProvider);
                    if ($nextProvider) {
                        $currentProvider = $nextProvider;
                        $this->writeLog("切换到备用服务商: {$currentProvider}");
                        continue; // 继续下一次尝试
                    } else {
                        $this->writeLog("无更多备用服务商可用");
                        break;
                    }
                } else {
                    $this->writeLog("所有服务商尝试完毕，生成失败");
                }
            }
        }

        // 构建详细的错误信息，包含服务商名称
        $providerNames = [
            'qianwen' => '阿里千问',
            'stable_diffusion' => 'Stable Diffusion',
            'stable_diffusion2' => 'Stable Diffusion 2'
        ];

        $lastProviderName = $providerNames[$lastTriedProvider] ?? $lastTriedProvider;
        $triedProviderNames = array_map(function($provider) use ($providerNames) {
            return $providerNames[$provider] ?? $provider;
        }, $triedProviders);

        $errorMsg = "所有AI图片生成服务商均不可用，最后尝试的服务商：{$lastProviderName}";
        if (count($triedProviderNames) > 1) {
            $errorMsg .= "，已尝试的服务商：" . implode('、', $triedProviderNames);
        }

        return json(['code' => 0, 'msg' => $errorMsg]);
    }



/**
 * 图片放大函数
 * @param int $width 放大前的宽度
 * @param int $height 放大前的高度
 * @return void 返回放大后的宽度*高度
 */
    function fangda($width, $height){
         //$width和$heigth,取小者的像素为1024,大者的像素按比例放大
         $minSize = min($width, $height);
         $maxSize = max($width, $height);
         $scale = $maxSize / $minSize;
         //看$width和$height,哪个大,哪个小的像素为1024,大的按比例放大
         if ($width > $height) {
             $newHeight = 1024;
             $newWidth = intval($newHeight * $scale);
         } else {
             $newWidth = 1024;
             $newHeight = intval($newWidth * $scale);
         }
         //如果放大后太大，最大的像素超过了2048,则按比例缩小
         if ($newWidth > 2048 || $newHeight > 2048) {
             $scale = 2048 / max($newWidth, $newHeight);
             $newWidth = intval($newWidth * $scale);
             $newHeight = intval($newHeight * $scale);
         }
         return [$newWidth,$newHeight];
    }

    /**
     * 测试AI配置
     */
    public function testConfig()
    {
        $this->writeLog("开始测试AI配置");

        $result = [
            'config_loaded' => is_array($this->aiConfig) && !empty($this->aiConfig),
            'config_type' => gettype($this->aiConfig),
            'config_count' => is_array($this->aiConfig) ? count($this->aiConfig) : 0,
            'default_provider' => $this->aiConfig['default_provider'] ?? '未设置',
            'file_exists' => file_exists(APP_PATH . 'extra/ai.php'),
            'file_readable' => is_readable(APP_PATH . 'extra/ai.php'),
        ];

        $this->writeLog("配置测试结果: " . json_encode($result));

        return json([
            'code' => 1,
            'msg' => '配置测试完成',
            'data' => $result
        ]);
    }

    /**
     * 测试千问API调用
     */
    public function testQianwenAPI()
    {
        $this->writeLog("开始测试千问API");

        try {
            // 简单的测试参数
            $prompt = "一只可爱的小猫";
            $apiKey = $this->aiConfig['qianwen']['api_key'];
            $apiUrl = $this->aiConfig['qianwen']['api_url'];
            $model = $this->aiConfig['qianwen']['model'];

            $data = [
                'model' => $model,
                'input' => [
                    'prompt' => $prompt
                ],
                'parameters' => [
                    'size' => '1024*1024',
                    'n' => 1
                ]
            ];

            $headers = [
                'Content-Type: application/json',
                'Authorization: Bearer ' . $apiKey,
                'X-DashScope-Async: enable'  // 启用异步模式
            ];

            $this->writeLog("千问API测试请求: " . json_encode($data, JSON_UNESCAPED_UNICODE));

            $ch = curl_init();
            curl_setopt_array($ch, [
                CURLOPT_URL => $apiUrl,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_POST => true,
                CURLOPT_POSTFIELDS => json_encode($data),
                CURLOPT_HTTPHEADER => $headers,
                CURLOPT_TIMEOUT => 60,
                CURLOPT_SSL_VERIFYPEER => false,
                CURLOPT_SSL_VERIFYHOST => false
            ]);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            $error = curl_error($ch);
            curl_close($ch);

            $this->writeLog("千问API响应状态: {$httpCode}");
            $this->writeLog("千问API响应内容: " . $response);

            if ($error) {
                throw new Exception('cURL错误: ' . $error);
            }

            $result = json_decode($response, true);

            // 处理异步响应
            if ($httpCode === 200 && isset($result['output']['task_id'])) {
                $taskId = $result['output']['task_id'];
                $this->writeLog("获取到任务ID: {$taskId}，开始轮询结果");

                try {
                    $imageUrl = $this->pollQianwenTask($taskId, $apiKey);
                    return json([
                        'code' => 1,
                        'msg' => '千问API异步调用成功',
                        'data' => [
                            'http_code' => $httpCode,
                            'task_id' => $taskId,
                            'image_url' => $imageUrl,
                            'success' => true
                        ]
                    ]);
                } catch (Exception $e) {
                    return json([
                        'code' => 0,
                        'msg' => '千问API轮询失败: ' . $e->getMessage(),
                        'data' => [
                            'http_code' => $httpCode,
                            'task_id' => $taskId,
                            'response' => $result
                        ]
                    ]);
                }
            }

            return json([
                'code' => $httpCode === 200 ? 1 : 0,
                'msg' => '千问API测试完成',
                'data' => [
                    'http_code' => $httpCode,
                    'response' => $result,
                    'success' => $httpCode === 200
                ]
            ]);

        } catch (Exception $e) {
            $this->writeLog("千问API测试失败: " . $e->getMessage(), 'error');
            return json([
                'code' => 0,
                'msg' => '千问API测试失败: ' . $e->getMessage()
            ]);
        }
    }



    /**
     * 测试AI连接
     */
    public function test()
    {
        return json([
            'code' => 1,
            'msg' => 'AI控制器连接正常',
            'data' => [
                'timestamp' => time(),
                'datetime' => date('Y-m-d H:i:s'),
                'config_loaded' => is_array($this->aiConfig) && !empty($this->aiConfig),
                'default_provider' => $this->aiConfig['default_provider'] ?? '未设置'
            ]
        ]);
    }

    /**
     * 测试AI图片生成（简化版本）
     */
    public function testGenerateImage()
    {
        if (!$this->request->isPost()) {
            $this->error('请求方式错误');
        }

        $prompt = $this->request->post('prompt', '');

        if (empty($prompt)) {
            $this->error('提示词不能为空');
        }

        // 记录调试信息
        \think\Log::record("AI图片生成测试请求: prompt={$prompt}", 'info');

        // 返回测试响应
        return json([
            'code' => 1,
            'msg' => 'AI图片生成测试成功',
            'data' => [
                'image_url' => '/uploads/test-ai-image.jpg',
                'original_url' => '/uploads/test-ai-image.jpg',
                'prompt' => $prompt,
                'size' => '1024*1024',
                'style' => 'default',
                'provider' => 'test'
            ]
        ]);
    }

    /**
     * AI文本生成
     */
    public function generateText()
    {
        if (!$this->request->isPost()) {
            return json(['code' => 0, 'msg' => '请求方式错误']);
        }

        // 检查AI配置是否加载成功
        if (!is_array($this->aiConfig) || empty($this->aiConfig)) {
            $this->writeLog("AI配置检查失败", 'error');
            return json(['code' => 0, 'msg' => 'AI配置未找到或格式错误']);
        }

        $prompt = $this->request->post('prompt', '');
        $type = $this->request->post('type', 'general');
        $maxTokens = $this->request->post('max_tokens', 1000);
        $temperature = $this->request->post('temperature', 0.7);
        $provider = $this->request->post('provider', $this->aiConfig['default_text_provider'] ?? 'qianwen');

        if (empty($prompt)) {
            return json(['code' => 0, 'msg' => '提示词不能为空']);
        }

        try {
            // 检查频率限制
            if (!$this->checkRateLimit()) {
                return json(['code' => 0, 'msg' => '请求过于频繁，请稍后再试']);
            }

            // 记录请求日志
            $this->writeLog("AI文本生成请求: {$prompt}");

            // 调用AI文本生成服务
            $this->writeLog("开始调用文本生成API");
            $generatedText = $this->callTextGenerationApi($prompt, $maxTokens, $temperature, $provider);
            $this->writeLog("文本生成API调用" . ($generatedText ? '成功' : '失败'));

            if ($generatedText) {
                return json([
                    'code' => 1,
                    'msg' => 'AI文本生成成功',
                    'data' => [
                        'content' => $generatedText,
                        'prompt' => $prompt,
                        'type' => $type,
                        'provider' => $provider,
                        'tokens_used' => mb_strlen($generatedText)
                    ]
                ]);
            } else {
                return json(['code' => 0, 'msg' => 'AI文本生成失败']);
            }
        } catch (Exception $e) {
            $this->writeLog("文本生成错误: " . $e->getMessage(), 'error');
            // 检查错误信息是否包含服务商信息，如果包含则直接返回，否则添加通用错误信息
            $errorMsg = $e->getMessage();
            if (strpos($errorMsg, '最后尝试的服务商') !== false) {
                return json(['code' => 0, 'msg' => $errorMsg]);
            } else {
                return json(['code' => 0, 'msg' => 'AI文本生成失败: ' . $errorMsg]);
            }
        }
    }

    /**
     * 批量生成图片
     */
    public function batchGenerate()
    {
        if (!$this->request->isPost()) {
            $this->error('请求方式错误');
        }

        $prompts = $this->request->post('prompts', []);
        $size = $this->request->post('size', '512x512');
        $style = $this->request->post('style', 'default');

        if (empty($prompts) || !is_array($prompts)) {
            $this->error('提示词数组不能为空');
        }

        $results = [];
        $errors = [];

        foreach ($prompts as $index => $prompt) {
            try {
                // 使用多服务商切换的图片生成方法
                $imageUrl = $this->generateImageWithFallback($prompt, $size, $style);
                if ($imageUrl) {
                    $localPath = $this->downloadAndSaveImage($imageUrl);
                    if ($localPath) {
                        $results[] = [
                            'index' => $index,
                            'prompt' => $prompt,
                            'image_url' => $localPath,
                            'original_url' => $imageUrl
                        ];
                    } else {
                        $errors[] = ['index' => $index, 'error' => '图片保存失败'];
                    }
                } else {
                    $errors[] = ['index' => $index, 'error' => 'AI图片生成失败'];
                }
            } catch (\Exception $e) {
                // 检查是否包含服务商信息
                $errorMsg = $e->getMessage();
                if (strpos($errorMsg, '最后尝试的服务商') !== false || strpos($errorMsg, '已尝试的服务商') !== false) {
                    $errors[] = ['index' => $index, 'error' => $errorMsg];
                } else {
                    $errors[] = ['index' => $index, 'error' => 'AI图片生成失败: ' . $errorMsg];
                }
            }
        }

        $this->success('批量生成完成', null, [
            'success_count' => count($results),
            'error_count' => count($errors),
            'results' => $results,
            'errors' => $errors
        ]);
    }

    /**
     * 获取AI生成历史记录
     */
    public function getHistory()
    {
        $page = $this->request->get('page', 1);
        $limit = $this->request->get('limit', 20);

        // 这里可以从数据库获取历史记录
        // 暂时返回空数据
        $this->success('获取成功', null, [
            'total' => 0,
            'rows' => []
        ]);
    }

    /**
     * 生成图片（支持多服务商自动切换）
     */
    private function generateImageWithFallback($prompt, $size = '1024*1024', $style = 'default')
    {
        // 解析尺寸
        if (strpos($size, '*') !== false) {
            list($width, $height) = explode('*', $size, 2);
        } elseif (strpos($size, 'x') !== false) {
            list($width, $height) = explode('x', $size, 2);
        } else {
            $width = $height = 1024;
        }

        $width = (int)$width;
        $height = (int)$height;

        // 获取当前服务商
        $currentProvider = $this->getCurrentProvider();
        $maxAttempts = count($this->providerPriority);
        $triedProviders = []; // 记录所有尝试过的服务商
        $lastTriedProvider = $currentProvider; // 记录最后尝试的服务商

        for ($attempt = 1; $attempt <= $maxAttempts; $attempt++) {
            try {
                $this->writeLog("图片生成第 {$attempt} 次尝试，使用服务商: {$currentProvider}");

                // 记录尝试过的服务商
                if (!in_array($currentProvider, $triedProviders)) {
                    $triedProviders[] = $currentProvider;
                }
                $lastTriedProvider = $currentProvider;

                // 应用风格后缀
                $styledPrompt = $this->applyStyle($prompt, $style);

                // 调用AI图片生成服务
                $imageUrl = $this->callAiApi($styledPrompt, $width, $height, $currentProvider, 'image');

                if ($imageUrl) {
                    $this->writeLog("图片生成成功，服务商: {$currentProvider}");
                    return $imageUrl;
                }

            } catch (\Exception $e) {
                $this->writeLog("服务商 {$currentProvider} 图片生成失败: " . $e->getMessage(), 'error');

                // 如果不是最后一次尝试，切换到下一个服务商
                if ($attempt < $maxAttempts) {
                    $nextProvider = $this->switchToNextProvider($currentProvider);
                    if ($nextProvider) {
                        $currentProvider = $nextProvider;
                        $this->writeLog("切换到备用图片生成服务商: {$currentProvider}");
                        continue;
                    } else {
                        $this->writeLog("无更多备用图片生成服务商可用");
                        break;
                    }
                }
            }
        }

        // 构建详细的错误信息，包含服务商名称
        $providerNames = [
            'qianwen' => '阿里千问',
            'openai' => 'OpenAI',
            'doubao' => '豆包AI',
            'stable_diffusion' => 'Stable Diffusion',
            'stable_diffusion2' => 'Stable Diffusion 2'
        ];

        $lastProviderName = $providerNames[$lastTriedProvider] ?? $lastTriedProvider;
        $triedProviderNames = array_map(function($provider) use ($providerNames) {
            return $providerNames[$provider] ?? $provider;
        }, $triedProviders);

        $errorMsg = "所有AI图片生成服务商均不可用，最后尝试的服务商：{$lastProviderName}";
        if (count($triedProviderNames) > 1) {
            $errorMsg .= "，已尝试的服务商：" . implode('、', $triedProviderNames);
        }

        throw new \Exception($errorMsg);
    }

    /**
     * 调用AI API生成图片（改进版）
     */
    private function callAiApi($prompt, $width=512, $height=512, $provider='qianwen', $type="image")
    {
        $this->writeLog("callAiApi开始，服务商: {$provider}");

        // 使用已经加载的配置
        $config = $this->aiConfig;
        //print_r($config);exit;
        if (!is_array($config)) {
            $this->writeLog("AI配置不可用", 'error');
            throw new Exception('AI配置不可用');
        }

        // 获取当前提供商的配置
        if (!isset($config[$provider]) || !is_array($config[$provider])) {
            throw new Exception("AI提供商配置不存在: {$provider}");
        }

        $providerConfig = $config[$provider];
        $apiKey = isset($providerConfig['api_key']) ? $providerConfig['api_key'] : '';
        $apiUrl = isset($providerConfig['api_url']) ? $providerConfig['api_url'] : '';
        $model = isset($providerConfig['model']) ? $providerConfig['model'] : '';

        if ($apiKey == null && $provider != "stable_diffusion"&& $provider != "stable_diffusion2") {
            throw new Exception('AI API密钥未配置，请设置环境变量 AI_' . strtoupper($provider) . '_KEY');
        }

        if (empty($apiUrl)) {
            throw new Exception("AI API URL未配置: {$provider}");
        }

        // 根据风格调整提示词
        $prompt="senior college, vocal music,  chinese,elderly student group, classroom setting,  teaching interaction, recreational activity, positive atmosphere, body movements, indoor environment, warm scene, vitality display";
        $negative_prompt= 'no pornographic elements, no text presentation, avoid pornographic content, no any text in the frame';

        $enhancedPrompt = $this->enhancePrompt($prompt, 'default');


        // 根据提供商调整请求数据格式
        $data = [];
        $headers = [];

        if ($provider === 'qianwen') {
            $size = $width . '*' . $height;
            
            // 检查尺寸是否支持
            $supportedSizes = isset($providerConfig['supported_sizes']) && is_array($providerConfig['supported_sizes'])
                ? $providerConfig['supported_sizes']
                : ['1024*1024'];

            if (!in_array($size, $supportedSizes)) {
                $size = isset($providerConfig['max_size']) ? $providerConfig['max_size'] : '1024*1024';
            }

            $data = [
                'model' => $model,
                'input' => [
                    'prompt' => $enhancedPrompt
                ],
                'parameters' => [
                    'size' => $size,
                    'n' => 1,
                    'seed' => rand(1, 999999),
                    'style' => '<auto>'
                ]
            ];

            $headers = [
                'Content-Type: application/json',
                'Authorization: Bearer ' . $apiKey,
                'X-DashScope-Async: enable'
            ];
        } else if (preg_match("/stable_diffusion/",$provider)) {

            $data = [
                'sd_model_checkpoint' =>'majicMIX realistic 麦橘写实_v7',
                'prompt' => $enhancedPrompt,
                'text_prompts' => [
                    ['text' => $enhancedPrompt]
                ],
                'cfg_scale' => 7,
                'height' => $height,
                'width' => $width,
                'samples' => 1,
                'steps' => 20,
                // 'styles' => [],  // 风格预设：空数组（不使用预设风格）
                // 'seed' => -1,  // 随机种子：-1 表示每次随机
                // 'subseed' => -1,  // 子种子：不启用
                // 'subseed_strength' => 0,  // 子种子强度：0 表示无影响
                // 'seed_resize_from_h' => -1,  // 种子缩放高度：不启用
                // 'seed_resize_from_w' => -1,  // 种子缩放宽度：不启用
                // 'negative_prompt'=> 'no pornographic elements, no text presentation, avoid pornographic content, no any text in the frame',
                // // 采样器与调度器（常用组合）
                // 'sampler_name' => 'Euler a',  // 采样器：常用且稳定的 Euler a
                // 'scheduler' => 'Automatic',  // 调度器：自动匹配采样器
                // 'sampler_index' => 'Euler',  // 采样器索引：与 sampler_name 匹配
                
                // // 生成数量与迭代
                // 'batch_size' => 1,  // 批量生成数量：一次生成1张
                // 'n_iter' => 1,  // 迭代次数：1轮迭代
                
                // // 优化与修复
                // 'restore_faces' => true,  // 人脸修复：启用（生成人物时推荐）
                // 'tiling' => false,  // 平铺模式：关闭（非纹理图无需平铺）
                
                // // 保存设置
                // 'do_not_save_samples' => false,  // 不保存单张图像：关闭（允许本地保存）
                // 'do_not_save_grid' => false,  // 不保存网格图：关闭
                // 'save_images' => false,  // 保存图像到本地：关闭（通过API返回）
                // 'send_images' => true,  // 响应中返回图像：启用（返回base64）
                
                // // 高级降噪参数（默认值）
                // 'eta' => 0,  // 噪声系数：0（确定性采样）
                // 'denoising_strength' => 0,  // 降噪强度：0（文生图无需降噪）
                // 's_min_uncond' => 0,  // 无条件采样起始步长：默认
                // 's_churn' => 0,  // 噪声扰动：0（不增加额外噪声）
                // 's_tmax' => 0,  // 最大温度：默认
                // 's_tmin' => 0,  // 最小温度：默认
                // 's_noise' => 0,  // 噪声缩放：默认
                
                // // 高清修复（HR）参数（关闭状态）
                // 'enable_hr' => false,  // 启用高清修复：关闭
                // 'firstphase_width' => 0,  // 第一阶段宽度：0（不启用）
                // 'firstphase_height' => 0,  // 第一阶段高度：0（不启用）
                // 'hr_scale' => 2,  // 高清缩放倍数：2（备用值）
                // 'hr_upscaler' => '',  // 高清放大算法：空（不启用）
                // 'hr_second_pass_steps' => 0,  // 高清修复步数：0
                // 'hr_resize_x' => 0,  // 高清修复目标宽度：0
                // 'hr_resize_y' => 0,  // 高清修复目标高度：0
                // 'hr_checkpoint_name' => '',  // 高清修复模型：空（不启用）
                // 'hr_sampler_name' => '',  // 高清修复采样器：空
                // 'hr_scheduler' => '',  // 高清修复调度器：空
                // 'hr_prompt' => '',  // 高清修复提示词：空
                // 'hr_negative_prompt' => '',  // 高清修复反向提示词：空
                
                // // 其他参数
                // 'override_settings' => [],  // 临时覆盖全局设置：空
                // 'override_settings_restore_afterwards' => true,  // 恢复全局设置：启用
                // 'refiner_checkpoint' => '',  // 精炼模型：空（不使用）
                // 'refiner_switch_at' => 0,  // 精炼切换步数：0
                // 'disable_extra_networks' => false,  // 禁用额外网络：关闭（允许加载LoRA等）
                // 'firstpass_image' => '',  // 第一阶段图像：空（文生图无需）
                // 'comments' => [],  // 备注信息：空
                // 'force_task_id' => '',  // 强制任务ID：空
                // 'script_name' => '',  // 脚本名称：空（不调用脚本）
                // 'script_args' => [],  // 脚本参数：空
                // 'alwayson_scripts' => [],  // 全局脚本：空
                // 'infotext' => ''  // 信息文本：空
            ];

            $headers = [
                'Content-Type: application/json',
                'Accept: application/json'
            ];
            //echo $apiUrl;exit;
            if (!empty($apiKey)) {
                $headers[] = 'Authorization: Bearer ' . $apiKey;
            }
        } else if ($provider === 'openai') {
            $data = [
                'model' => $model,
                'prompt' => $enhancedPrompt,
                'n' => 1,
                'size' => $width . 'x' . $height
            ];

            $headers = [
                'Content-Type: application/json',
                'Authorization: Bearer ' . $apiKey
            ];
        }

        $this->writeLog("API请求数据: " . json_encode($data, JSON_UNESCAPED_UNICODE));

        // 发送HTTP请求
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $apiUrl,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => json_encode($data),
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_TIMEOUT => 120, // 2分钟超时
            CURLOPT_CONNECTTIMEOUT => 10, // 10秒连接超时
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false
        ]);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $curlError = curl_error($ch);
        curl_close($ch);

        // 检查cURL错误
        if ($response === false || !empty($curlError)) {
            $errorMsg = "网络连接失败: {$curlError}";
            $this->writeLog($errorMsg, 'error');
            throw new Exception($errorMsg);
        }

        // 检查HTTP状态码
        if ($httpCode >= 400) {
            $errorMsg = "API请求失败，HTTP状态码: {$httpCode}，响应: " . substr($response, 0, 500);
            $this->writeLog($errorMsg, 'error');
            throw new Exception($errorMsg);
        }

        $this->writeLog("API响应: " . substr($response, 0, 500));

        $result = json_decode($response, true);
        if (!$result) {
            throw new Exception('API响应JSON解析失败');
        }

        // 根据不同API提供商解析响应
        $imageUrl = null;
        if ($provider === 'qianwen') {
            if (isset($result['output']['task_id'])) {
                $taskId = $result['output']['task_id'];
                $this->writeLog("千问API返回任务ID: {$taskId}");
                $imageUrl = $this->pollQianwenTask($taskId, $apiKey);
            } elseif (isset($result['output']['results'][0]['url'])) {
                $imageUrl = $result['output']['results'][0]['url'];
            }
        } else if (preg_match("/stable_diffusion/",$provider)) {
            if (isset($result['images'][0])) {
                $base64Image = $result['images'][0];
                $imageUrl = $this->saveBase64Image($base64Image);
            } elseif (isset($result['url'])) {
                $imageUrl = $result['url'];
            }
        } else if ($provider === 'openai') {
            if (isset($result['data'][0]['url'])) {
                $imageUrl = $result['data'][0]['url'];
            }
        }

        if (!$imageUrl) {
            $this->writeLog("无法从响应中提取图片URL", 'error');
            throw new Exception('API响应中未找到图片URL');
        }

        $this->writeLog("成功获取图片URL: {$imageUrl}");
        return $imageUrl;
    }

    /**
     * 轮询千问异步任务结果
     * @param string $taskId 任务ID
     * @param string $apiKey API密钥
     * @return string 图片URL
     */
    private function pollQianwenTask($taskId, $apiKey)
    {
        $maxAttempts = 40; // 最多轮询40次
        $interval = 3; // 每3秒轮询一次
        $queryUrl = "https://dashscope.aliyuncs.com/api/v1/tasks/{$taskId}";

        $this->writeLog("开始轮询千问任务: {$taskId}");

        for ($i = 0; $i < $maxAttempts; $i++) {
            sleep($interval);

            $ch = curl_init();
            curl_setopt_array($ch, [
                CURLOPT_URL => $queryUrl,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_HTTPHEADER => [
                    'Authorization: Bearer ' . $apiKey,
                    'Content-Type: application/json'
                ],
                CURLOPT_TIMEOUT => 30,
                CURLOPT_SSL_VERIFYPEER => false,
                CURLOPT_SSL_VERIFYHOST => false
            ]);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            $error = curl_error($ch);
            curl_close($ch);

            $this->writeLog("轮询第" . ($i + 1) . "次，状态码: {$httpCode}");

            if ($error) {
                $this->writeLog("轮询cURL错误: {$error}", 'error');
                continue;
            }

            if ($httpCode === 200) {
                $result = json_decode($response, true);
                $this->writeLog("轮询响应: " . json_encode($result, JSON_UNESCAPED_UNICODE));

                if (isset($result['output']['task_status'])) {
                    $status = $result['output']['task_status'];
                    $this->writeLog("任务状态: {$status}");

                    if ($status === 'SUCCEEDED') {
                        if (isset($result['output']['results'][0]['url'])) {
                            $imageUrl = $result['output']['results'][0]['url'];
                            $this->writeLog("任务完成，获取到图片URL: {$imageUrl}");
                            return $imageUrl;
                        } else {
                            $this->writeLog("任务成功但未找到图片URL", 'error');
                            throw new Exception("任务成功但未找到图片URL");
                        }
                    } elseif ($status === 'FAILED') {
                        $error = $result['output']['message'] ?? $result['message'] ?? '任务失败';
                        $this->writeLog("任务失败: {$error}", 'error');
                        throw new Exception("千问任务失败: {$error}");
                    }
                    // PENDING 或 RUNNING 状态继续轮询
                } else {
                    $this->writeLog("轮询响应中没有任务状态", 'warning');
                }
            } else {
                $this->writeLog("轮询请求失败，状态码: {$httpCode}，响应: " . substr($response, 0, 200), 'error');
            }
        }

        throw new Exception("千问任务轮询超时，已轮询{$maxAttempts}次");
    }

    /**
     * 增强提示词
     * @param string $prompt 原始提示词
     * @param string $style 风格
     * @return string
     */
    private function enhancePrompt($prompt, $style)
    {
        $stylePrompts = [
            'modern' => ', modern style, clean design, minimalist',
            'cartoon' => ', cartoon style, colorful, friendly',
            'realistic' => ', photorealistic, high quality, detailed',
            'artistic' => ', artistic style, creative, expressive',
            'professional' => ', professional style, business-like, clean',
            'educational' => ', educational theme, learning-focused, inspiring',
            'default' => ''
        ];

        $styleAddition = $stylePrompts[$style] ?? $stylePrompts['default'];

        return $prompt . $styleAddition . ', high quality, 4k resolution';
    }

    /**
     * 下载并保存图片到本地
     * @param string $imageUrl 图片URL
     * @return string|false
     */
    private function downloadAndSaveImage($imageUrl)
    {
        try {
            $config = $this->aiConfig;
            if(substr($imageUrl, 0, 1) == '/'){
                return $imageUrl;
            }
            // 创建保存目录
            $uploadDir = ROOT_PATH . 'public/' . $config['upload_path'] . date('Y/m/d/');
            if (!is_dir($uploadDir)) {
                mkdir($uploadDir, 0755, true);
            }

            // 生成文件名
            $fileName = 'ai_' . time() . '_' . uniqid() . '.png';
            $filePath = $uploadDir . $fileName;

            // 下载图片
            $context = stream_context_create([
                'http' => [
                    'timeout' => 30,
                    'user_agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
                ]
            ]);

            $imageData = file_get_contents($imageUrl, false, $context);
            if ($imageData && file_put_contents($filePath, $imageData)) {
                // 返回相对路径
                return '/' . $config['upload_path'] . date('Y/m/d/') . $fileName;
            }
        } catch (\Exception $e) {
            throw new Exception('图片下载失败: ' . $e->getMessage());
        }

        return false;
    }
    
    /**
     * 获取支持的图片尺寸
     */
    public function getSupportedSizes()
    {
        $config = $this->aiConfig;
        $provider = $config['default_provider'] ?? 'doubao';
        $providerConfig = $config[$provider] ?? $config['doubao'];

        $this->success('获取成功', null, [
            'provider' => $provider,
            'sizes' => $providerConfig['supported_sizes'],
            'default_size' => $config['default_size']
        ]);
    }

    /**
     * 获取支持的图片风格
     */
    public function getSupportedStyles()
    {
        $config = config('ai.');
        $styles = [];

        foreach ($config['styles'] as $key => $style) {
            $styles[] = [
                'key' => $key,
                'name' => $style['name']
            ];
        }

        $this->success('获取成功', null, ['styles' => $styles]);
    }

    /**
     * 获取当前AI服务商信息
     */
    public function getProviderInfo()
    {
        $config = config('ai.');
        $provider = $config['default_provider'] ?? 'doubao';
        $providerConfig = $config[$provider] ?? $config['doubao'];

        $providerNames = [
            'openai' => 'OpenAI DALL-E',
            'doubao' => '豆包AI Seedream'
        ];

        $this->success('获取成功', null, [
            'provider' => $provider,
            'provider_name' => $providerNames[$provider] ?? $provider,
            'model' => $providerConfig['model'],
            'api_configured' => !empty($providerConfig['api_key'])
        ]);
    }

    /**
     * 测试AI连接
     */
    public function testConnection()
    {
        try {
            $testPrompt = "A simple test image";
            // 使用多服务商切换的图片生成方法
            $result = $this->generateImageWithFallback($testPrompt, '512*512', 'default');

            if ($result) {
                $this->success('AI连接测试成功', null, ['test_url' => $result]);
            } else {
                $this->error('AI连接测试失败');
            }
        } catch (\Exception $e) {
            // 检查是否包含服务商信息
            $errorMsg = $e->getMessage();
            if (strpos($errorMsg, '最后尝试的服务商') !== false || strpos($errorMsg, '已尝试的服务商') !== false) {
                $this->error($errorMsg);
            } else {
                $this->error('连接测试失败: ' . $errorMsg);
            }
        }
    }

    /**
     * AI生成文本内容
     */
    public function generateText2()
    {
        if (!$this->request->isPost()) {
            $this->error('请求方式错误');
        }

        $prompt = $this->request->post('prompt', '');
        $maxTokens = $this->request->post('max_tokens', 500);

        if (empty($prompt)) {
            $this->error('提示词不能为空');
        }

        try {
            // 调用AI文本生成服务
            $text = $this->callTextGenerationApi($prompt, $maxTokens);

            if ($text) {
                $this->success('文本生成成功', null, [
                    'text' => $text,
                    'prompt' => $prompt,
                    'tokens_used' => mb_strlen($text, 'utf-8')
                ]);
            } else {
                $this->error('文本生成失败，请重试');
            }
        } catch (\Exception $e) {
            $this->error('生成失败: ' . $e->getMessage());
        }
    }

    /**
     * 调用AI文本生成API（支持多服务商自动切换）
     * @param string $prompt 提示词
     * @param int $maxTokens 最大token数
     * @param float $temperature 温度参数
     * @param string $provider 指定服务商
     * @return string|false
     */
    private function callTextGenerationApi($prompt, $maxTokens = 500, $temperature = 0.7, $provider = null)
    {
        $config = $this->aiConfig;

        // 文本生成的服务商优先级
        $textProviderPriority = ['qianwen', 'openai', 'doubao'];

        // 获取当前服务商
        $currentProvider = $provider ?: ($config['default_text_provider'] ?? 'qianwen');
        $maxAttempts = count($textProviderPriority);
        $lastTriedProvider = $currentProvider; // 记录最后尝试的服务商

        for ($attempt = 1; $attempt <= $maxAttempts; $attempt++) {
            try {
                $this->writeLog("文本生成第 {$attempt} 次尝试，使用服务商: {$currentProvider}");
                $lastTriedProvider = $currentProvider; // 更新最后尝试的服务商

                // 根据服务商调用对应的API
                if ($currentProvider === 'openai') {
                    $result = $this->callOpenAITextApi($prompt, $maxTokens, $config);
                } else if ($currentProvider === 'qianwen') {
                    $result = $this->callQianwenTextApi($prompt, $maxTokens, $config);
                } else if ($currentProvider === 'doubao') {
                    $result = $this->callDoubaoTextApi($prompt, $maxTokens, $config);
                } else {
                    throw new \Exception("不支持的文本生成服务商: {$currentProvider}");
                }

                if ($result) {
                    $this->writeLog("文本生成成功，服务商: {$currentProvider}");
                    return $result;
                }

            } catch (\Exception $e) {
                $this->writeLog("服务商 {$currentProvider} 文本生成失败: " . $e->getMessage(), 'error');

                // 如果不是最后一次尝试，切换到下一个服务商
                if ($attempt < $maxAttempts) {
                    $nextProvider = $this->getNextTextProvider($currentProvider, $textProviderPriority);
                    if ($nextProvider) {
                        $currentProvider = $nextProvider;
                        $this->writeLog("切换到备用文本生成服务商: {$currentProvider}");
                        continue;
                    } else {
                        $this->writeLog("无更多备用文本生成服务商可用");
                        break;
                    }
                }
            }
        }

        // 所有服务商都失败时，抛出包含最后尝试服务商名称的异常
        $providerNames = [
            'qianwen' => '阿里千问',
            'openai' => 'OpenAI',
            'doubao' => '豆包AI'
        ];
        $lastProviderName = $providerNames[$lastTriedProvider] ?? $lastTriedProvider;

        throw new \Exception("所有AI文本生成服务商均不可用，最后尝试的服务商：{$lastProviderName}");
    }

    /**
     * 获取下一个文本生成服务商
     */
    private function getNextTextProvider($currentProvider, $providerPriority)
    {
        $currentIndex = array_search($currentProvider, $providerPriority);

        if ($currentIndex === false) {
            $currentIndex = 0;
        }

        // 获取下一个服务商
        $nextIndex = $currentIndex + 1;
        if ($nextIndex >= count($providerPriority)) {
            return null; // 无更多备用
        }

        return $providerPriority[$nextIndex];
    }

    /**
     * 调用OpenAI文本生成API
     */
    private function callOpenAITextApi($prompt, $maxTokens, $config)
    {
        $apiKey = $config['openai']['api_key'] ?? '';
        $apiUrl = $config['openai']['text_api_url'] ?? 'https://api.openai.com/v1/chat/completions';

        if (empty($apiKey)) {
            throw new Exception('OpenAI API密钥未配置');
        }

        $data = [
            'model' => $config['openai']['text_model'] ?? 'gpt-3.5-turbo',
            'messages' => [
                [
                    'role' => 'user',
                    'content' => $prompt
                ]
            ],
            'max_tokens' => $maxTokens,
            'temperature' => 0.7
        ];

        $headers = [
            'Authorization: Bearer ' . $apiKey,
            'Content-Type: application/json'
        ];

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 60);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode !== 200) {
            throw new Exception('OpenAI API请求失败，HTTP状态码: ' . $httpCode);
        }

        $result = json_decode($response, true);
        if (isset($result['choices'][0]['message']['content'])) {
            return trim($result['choices'][0]['message']['content']);
        }

        throw new Exception('OpenAI API返回格式错误');
    }

    /**
     * 调用豆包AI文本生成API
     */
    private function callDoubaoTextApi($prompt, $maxTokens, $config)
    {
        $apiKey = $config['doubao']['api_key'] ?? '';
        $apiUrl = $config['doubao']['text_api_url'] ?? 'https://ark.cn-beijing.volces.com/api/v3/chat/completions';

        if (empty($apiKey)) {
            throw new Exception('豆包AI API密钥未配置');
        }

        $data = [
            'model' => $config['doubao']['text_model'] ?? 'doubao-pro-4k',
            'messages' => [
                [
                    'role' => 'user',
                    'content' => $prompt
                ]
            ],
            'max_tokens' => $maxTokens,
            'temperature' => 0.7
        ];

        $headers = [
            'Authorization: Bearer ' . $apiKey,
            'Content-Type: application/json'
        ];

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 60);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode !== 200) {
            throw new Exception('豆包AI API请求失败，HTTP状态码: ' . $httpCode);
        }

        $result = json_decode($response, true);
        if (isset($result['choices'][0]['message']['content'])) {
            return trim($result['choices'][0]['message']['content']);
        }

        throw new Exception('豆包AI API返回格式错误');
    }

    /**
     * 调用阿里千问(通义千问)文本生成API
     */
    private function callQianwenTextApi($prompt, $maxTokens, $config, $temperature = 0.7)
    {
            $apiKey = $config['qianwen']['api_key'] ?? '';
            $apiUrl = $config['qianwen']['text_api_url'] ?? 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';

            if (empty($apiKey)) {
                throw new Exception('阿里千问 API密钥未配置');
            }

            $this->writeLog("调用千问API: {$apiUrl}");

            $data = [
                'model' => $config['qianwen']['text_model'] ?? 'qwen-turbo',
                'input' => [
                    'messages' => [
                        [
                            'role' => 'user',
                            'content' => $prompt
                        ]
                    ]
                ],
                'parameters' => [
                    'max_tokens' => (string)$maxTokens,
                    'temperature' => (float)$temperature
                ]
            ];

            $this->writeLog("请求数据: " . json_encode($data, JSON_UNESCAPED_UNICODE));

            $headers = [
                'Authorization: Bearer ' . $apiKey,
                'Content-Type: application/json'
            ];

            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $apiUrl);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, 60);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            $this->writeLog("API响应状态: {$httpCode}");
            $this->writeLog("API响应内容: " . substr($response, 0, 500) . "...");

            if ($httpCode !== 200) {
                $this->writeLog("阿里千问 API请求失败，HTTP状态码: {$httpCode}，响应: {$response}", 'error');
                throw new Exception('阿里千问 API请求失败，HTTP状态码: ' . $httpCode . '，响应: ' . $response);
            }

            $result = json_decode($response, true);
            if (isset($result['output']['text'])) {
                $text = trim($result['output']['text']);
                $this->writeLog("AI文本生成成功，长度: " . mb_strlen($text));
                return $text;
            }

            $this->writeLog("阿里千问 API返回格式错误: " . json_encode($result), 'error');
            throw new Exception('阿里千问 API返回格式错误');
        }

    /**
     * 检查频率限制
     */
    private function checkRateLimit()
    {
        $key = 'ai_rate_limit_' . $this->request->ip();
        $count = Cache::get($key, 0);

        // 安全地获取限制配置
        $limit = 10; // 默认每分钟10次
        if (is_array($this->aiConfig) && isset($this->aiConfig['rate_limit'])) {
            $rateConfig = $this->aiConfig['rate_limit'];
            if (is_array($rateConfig) && isset($rateConfig['max_requests'])) {
                $limit = (int)$rateConfig['max_requests'];
            } elseif (is_numeric($rateConfig)) {
                $limit = (int)$rateConfig;
            }
        }

        if ($count >= $limit) {
            return false;
        }

        Cache::set($key, $count + 1, 60); // 1分钟过期
        return true;
    }

    /**
     * 应用风格到提示词
     */
    private function applyStyle($prompt, $style)
    {
        if (!is_array($this->aiConfig) || !isset($this->aiConfig['styles'])) {
            return $prompt;
        }

        $styles = $this->aiConfig['styles'];
        if (!is_array($styles) || !is_string($style) || !isset($styles[$style])) {
            return $prompt;
        }

        $styleConfig = $styles[$style];
        if (!is_array($styleConfig)) {
            return $prompt;
        }

        $prefix = isset($styleConfig['prefix']) ? $styleConfig['prefix'] : '';
        $suffix = isset($styleConfig['suffix']) ? $styleConfig['suffix'] : '';

        return $prefix . $prompt . $suffix;
    }

    /**
     * 记录请求日志
     */
    private function logRequest($action, $data)
    {
        Log::info("AI请求: {$action}", [
            'ip' => $this->request->ip(),
            'user_agent' => $this->request->header('User-Agent'),
            'data' => $data,
            'timestamp' => date('Y-m-d H:i:s')
        ]);
    }

    /**
     * 记录错误日志
     */
    private function logError($action, $error)
    {
        Log::error("AI错误: {$action}", [
            'error' => $error,
            'ip' => $this->request->ip(),
            'timestamp' => date('Y-m-d H:i:s')
        ]);
    }

    /**
     * 保存base64图片到服务器
     * @param string $base64Image base64编码的图片数据
     * @return string 图片URL
     */
    private function saveBase64Image($base64Image)
    {
        // 移除base64前缀（如果存在）
        if (strpos($base64Image, 'data:image/') === 0) {
            $base64Image = substr($base64Image, strpos($base64Image, ',') + 1);
        }

        // 生成唯一文件名
        $filename = 'ai_' . date('YmdHis') . '_' . uniqid() . '.png';
        $uploadPath = ROOT_PATH . 'public/uploads/ai_images/';

        // 确保目录存在
        if (!is_dir($uploadPath)) {
            mkdir($uploadPath, 0755, true);
        }

        // 保存图片
        $filePath = $uploadPath . $filename;
        if (file_put_contents($filePath, base64_decode($base64Image))) {
            $this->writeLog("成功保存图片到: {$filePath}");
            return '/uploads/ai_images/' . $filename;
        }

        $this->writeLog("保存图片失败", 'error');
        throw new Exception('保存图片失败');
    }

    /**
     * 获取当前服务商状态
     */
    public function getProviderStatus()
    {
        $switchInfo = Cache::get($this->providerSwitchKey);
        $currentProvider = $this->getCurrentProvider();
        
        $status = [
            'current_provider' => $currentProvider,
            'default_provider' => $this->aiConfig['default_provider'] ?? 'qianwen',
            'is_switched' => !empty($switchInfo),
            'switch_info' => $switchInfo,
            'provider_priority' => $this->providerPriority
        ];
        
        if ($switchInfo) {
            $remainingTime = $this->switchDuration - (time() - ($switchInfo['switch_time'] ?? 0));
            $status['remaining_time'] = max(0, $remainingTime);
        }
        
        return json([
            'code' => 1,
            'msg' => '获取状态成功',
            'data' => $status
        ]);
    }

    /**
     * 手动重置服务商（用于调试）
     */
    public function resetProvider()
    {
        Cache::rm($this->providerSwitchKey);
        $this->writeLog("手动重置服务商切换状态");
        
        return json([
            'code' => 1,
            'msg' => '服务商状态已重置',
            'data' => [
                'current_provider' => $this->getCurrentProvider()
            ]
        ]);
    }
}
